#pragma once
#include <vector>
#include <gcc-plugin.h>
#include <insn-modes.h>
#include <plugin.h>
#include <rtl.h>
#include <system.h>
#include <tree-core.h>
#include <tree-pass.h>
#include <target.h>
#include <tree.h>
#include <coretypes.h>
#include <gimple.h>
#include <gimple-iterator.h>
void register_plugin_pass(const char *base_name, opt_pass *pass, const char *ref, int refnum, enum pass_positioning_ops op);
class nohp_plugin_module;
class nohp_builtin_function;
class nohp_plugin_module {
public:
  nohp_plugin_module(){}
  virtual void add_passes(){}
  virtual void add_builtins(){}
  virtual void add_attributes(){}
  virtual void post_builtins(tree last){}
};
class nohp_builtin_function {
public:
  virtual rtx expand(tree exp, rtx target, rtx subtarget, machine_mode mode, int ignore){gcc_unreachable();}
  virtual tree type(){gcc_unreachable();}
  virtual tree fold(tree, int, tree*, bool){return NULL_TREE;}
  virtual bool gimple_fold(gimple_stmt_iterator *gsi){return false;};
  virtual void post_decl(){}
  const char *name;
  tree decl;
};

namespace nohp{
  extern std::vector<nohp_plugin_module*> modules;
  extern std::vector<nohp_builtin_function*> builtins;
  extern struct plugin_name_args *plugin_info;
  extern int current_builtin_code;
  extern gcc_target targetm_default;
  void register_module(nohp_plugin_module *module);
  void initialize_modules_and_overrides();
  void add_builtin(nohp_builtin_function *func);
  void add_attribute(const attribute_spec *spec);
  void register_pass(opt_pass *pass, const char *ref, int refnum, enum pass_positioning_ops op);
}
